package com.ztman.service.work.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ztman.basic.context.ContextUtil;
import com.ztman.basic.exception.BizException;
import com.ztman.service.authority.entity.auth.User;
import com.ztman.service.authority.entity.auth.UserRole;
import com.ztman.service.authority.service.auth.UserRoleService;
import com.ztman.service.authority.service.auth.UserService;
import com.ztman.service.authority.service.core.OrgService;
import com.ztman.service.work.entity.ProcessInfo;
import com.ztman.service.work.entity.WorkOrderCirculationHistory;
import com.ztman.service.work.entity.WorkOrderInfo;
import com.ztman.service.work.entity.WorkOrderTplData;
import com.ztman.service.work.service.ProcessInfoService;
import com.ztman.service.work.service.WorkOrderCirculationHistoryService;
import com.ztman.service.work.service.WorkOrderInfoService;
import com.ztman.service.work.service.WorkOrderTplDataService;
import com.ztman.service.work.vo.HandleParamVO;
import lombok.Data;

import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: wsd
 * @date: 2021/9/13 11:19
 */
public class Handle {
    private WorkOrderCirculationHistoryService workOrderCirculationHistoryService;
    private WorkOrderInfoService workOrderInfoService;
    private ProcessInfoService processInfoService;
    private WorkOrderTplDataService workOrderTplDataService;
    private UserService userService;
    private OrgService orgService;
    private UserRoleService userRoleService;
    private List<WorkOrderCirculationHistory> cirHistoryList;
    public List<JSONObject> workOrderData = new ArrayList<>();
    public JSONObject stateValue = new JSONObject();
    public JSONObject targetStateValue = new JSONObject();
    public List<WorkOrderTplData> workOrderTplData;
    private WorkOrderInfo workOrderDetails;
    private Integer flowProperties;
    private Long workOrderId;
    private Boolean endHistory = null;
    private Boolean condExprStatus  = null;
    Handle(){}
    Handle(WorkOrderCirculationHistoryService workOrderCirculationHistoryService
            ,WorkOrderInfoService workOrderInfoService
            ,ProcessInfoService processInfoService
            ,WorkOrderTplDataService workOrderTplDataService
            ,UserService userService
            ,OrgService orgService
            ,UserRoleService userRoleService

    ){
        this.workOrderCirculationHistoryService = workOrderCirculationHistoryService;
        this.workOrderInfoService = workOrderInfoService;
        this.processInfoService = processInfoService;
        this.workOrderTplDataService = workOrderTplDataService;
        this.userService = userService;
        this.orgService = orgService;
        this.userRoleService = userRoleService;
    }

    private  JSONObject updateValue = new JSONObject();

    public JSONArray Countersign(WorkOrderInfo workOrderDetails) {
        this.workOrderDetails = workOrderDetails;
        JSONArray stateList = workOrderDetails.getState();

        Map<String, Object> innerMap = new HashMap<>();
        Map<String, String> stateIdMap = new HashMap<>();
        JSONObject currentState = new JSONObject();
        this.cirHistoryList = workOrderCirculationHistoryService.list(new QueryWrapper<>(new WorkOrderCirculationHistory()).eq("work_order", workOrderDetails.getId()));
        for (int i = 0; i < stateList.size(); i++) {
            JSONObject v = stateList.getJSONObject(i);
            stateIdMap.put(v.getString("id"), v.getString("label"));
            if (v.getString("id").equals(this.stateValue.get("id"))) {
                currentState = v;
            }
        }
        Long loginUserId = ContextUtil.getUserId();
        int userStatusCount = 0;
        int cirHistoryCount = 0;
        boolean circulationStatus = false;
        for (int i = 0; i < this.cirHistoryList.size(); i++) {
            WorkOrderCirculationHistory cirHistoryValue = this.cirHistoryList.get(i);
            JSONArray processor = currentState.getJSONArray("processor");
            if (processor.size() > 1) {
                if (stateIdMap.get(cirHistoryValue.getSource()).isEmpty()) {
                    break;
                }
            }
            //用户会签
            if ("person".equals(currentState.getString("process_method"))) {
                for (int j = 0; j < processor.size(); j++) {
                    if (!cirHistoryValue.getProcessorId().equals(loginUserId) &&
                            cirHistoryValue.getSource().equals(currentState.getString("id")) &&
                            cirHistoryValue.getProcessorId().equals(processor.getString(i))) {
                        cirHistoryCount += 1;
                    }
                }
                if (cirHistoryCount == (processor.size() - 1)) {
                    circulationStatus = true;
                    break;
                }
            }
            if ("role".equals(currentState.getString("process_method")) || "department".equals(currentState.getString("process_method"))) {

                List<User> tmpUserList = new ArrayList<>();
                List<User> userInfoList = new ArrayList<>();
                if (stateValue.getBoolean("fullHandle") == true) {
                    //全员处理 会签
                    if ("role".equals(currentState.getString("process_method"))) {
                        List<UserRole> list = userRoleService.list(new QueryWrapper<>(new UserRole()).in("role_id", currentState.getJSONArray("processor")));
                        List<Long> userIds = list.stream().map(UserRole::getUserId).collect(Collectors.toList());
                        userInfoList = userService.listByIds(userIds);

                    }
                    if ("department".equals(currentState.getString("process_method"))) {
                        userInfoList = userService.list(new QueryWrapper<>(new User()).in("org_id", currentState.getJSONArray("processor")));
                    }
                    JSONObject temp = new JSONObject();
                    userInfoList.forEach(uf -> {
                        if (temp.getString(uf.getName()).isEmpty()) {
                            temp.put(uf.getName(), uf.getAccount());
                            tmpUserList.add(uf);
                        }
                    });
                    for (User user : tmpUserList) {
                        if (cirHistoryValue.getSource().equals(currentState.getString("id")) &&
                                !cirHistoryValue.getProcessorId().equals(loginUserId) &&
                                cirHistoryValue.getProcessorId().equals(user.getId())) {
                            userStatusCount += 1;
                            break;
                        }
                    }

                } else {
                    //普通会签
                    for (int j = 0; j < processor.size(); j++) {
                        if ("role".equals(currentState.getString("process_method"))) {
                            List<UserRole> list = userRoleService.list(new QueryWrapper<>(new UserRole()).in("role_id", currentState.getJSONArray("processor")));
                            List<Long> userIds = list.stream().map(UserRole::getUserId).collect(Collectors.toList());
                            userInfoList = userService.listByIds(userIds);

                        }
                        if ("department".equals(currentState.getString("process_method"))) {
                            userInfoList = userService.list(new QueryWrapper<>(new User()).in("org_id", currentState.getJSONArray("processor")));
                        }
                        for (User user : userInfoList) {
                            if (cirHistoryValue.getSource().equals(currentState.getString("id")) &&
                                    !cirHistoryValue.getProcessorId().equals(loginUserId) &&
                                    cirHistoryValue.getProcessorId().equals(user.getId())) {
                                userStatusCount += 1;
                                break;
                            }
                        }
                    }
                }
                if (stateValue.getBoolean("fullHandle") == true) {
                    if (userStatusCount == tmpUserList.size()) {
                        circulationStatus = true;
                    }
                } else {
                    if(userStatusCount == (processor.size()-1)){
                        circulationStatus = true;
                    }

                }

            }


        }
        if(circulationStatus){
            this.endHistory = true;
        }


        return new JSONArray();
    }
    public boolean circulation(){
        JSONArray stateValue = new JSONArray();
        JSONArray steteList = new JSONArray();
        JSONArray updateValueJSONArray = this.updateValue.getJSONArray("state");
        for (int i = 0; i < updateValueJSONArray.size(); i++) {
            steteList.add(updateValueJSONArray.getJSONObject(i));
        }
        StateController stateController = new StateController(userService,orgService);
        stateController.GetVariableValue(steteList, this.workOrderDetails.getCreatedBy());
        stateValue = this.updateValue.getJSONArray("state");
        WorkOrderInfo updateWorkOrderInfo = new WorkOrderInfo();
        updateWorkOrderInfo.setId(this.workOrderDetails.getId());
        updateWorkOrderInfo.setState(stateValue);
        updateWorkOrderInfo.setRelatedPerson(this.updateValue.getJSONArray("related_person"));
        boolean b =this.workOrderInfoService.updateById(updateWorkOrderInfo);
        if(!b){
            throw new BizException("工单修改失败");
        }
        // 如果是跳转到结束节点，则需要修改节点状态
        if ("end".equals(this.targetStateValue.getString("clazz"))) {
            WorkOrderInfo updateWorkOrderEnd = new WorkOrderInfo();
            updateWorkOrderEnd.setId(this.workOrderDetails.getId());
            updateWorkOrderEnd.setIsEnd(1);
            boolean b2 = workOrderInfoService.updateById(updateWorkOrderInfo);
            if(!b2){
                throw new BizException("修改结束节点失败");
            }
        }
        return true;
    }

    public  Boolean ConditionalJudgment(JSONObject condExpr) {
        Boolean condExprOk = false;
        Object condExprValue = null;

        for (int i = 0; i < this.workOrderTplData.size(); i++) {
            JSONObject formData = this.workOrderTplData.get(i).getFormData();
            if(!formData.getString(condExpr.getString("key")).isEmpty()){
                condExprValue = formData.get(condExpr.getString("key"));
                break;
            }
        }
        if (condExprValue == null) {
            throw  new BizException("表单数据为空");
        }
        String sign = "sign";
        String value = "value";
        Handle.Expr expr = new Handle.Expr();
        List<String> fh = expr.fh;
        if(condExprValue instanceof String){
            switch (condExpr.getString(sign)) {
                case "==":
                    if(condExprValue.equals(condExpr.getString(value))){
                        return true;
                    }
                    break;
                case "!=":
                    if(!condExprValue.equals(condExpr.getString(value))){
                        return true;
                    }
                    break;
                case ">":
                    if (Integer.valueOf(String.valueOf(condExprValue)) > condExpr.getIntValue(value)) {
                        return true;
                    }
                    break;
                case "<":
                    if (Integer.valueOf(String.valueOf(condExprValue)) < condExpr.getIntValue(value)) {
                        return true;
                    }
                    break;
                case ">=":
                    if (Integer.valueOf(String.valueOf(condExprValue)) >= condExpr.getIntValue(value)) {
                        return true;
                    }
                    break;
                case "<=":
                    if (Integer.valueOf(String.valueOf(condExprValue)) <= condExpr.getIntValue(value)) {
                        return true;
                    }
                    break;
                default:
                    new BizException("字符串类型只支持 == 和 ！= ");
                    break;
            }
        }else if(condExprValue instanceof Number){
            System.out.println("是个Integer 参数");
            int num = ((Number) condExprValue).intValue();
            if (fh.contains(condExpr.getString(sign)) ) {
                switch (condExpr.getString(sign)) {
                    case "==":
                        if (num == condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    case "!=":
                        if (num != condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    case ">":
                        if (num > condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    case "<":
                        if (num < condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    case ">=":
                        if (num >= condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    case "<=":
                        if (num <= condExpr.getIntValue(sign)) {
                            return true;
                        }
                        break;
                    default:
                        new BizException("目前仅支持6种常规判断类型，包括（等于、不等于、大于、大于等于、小于、小于等于）");
                        break;
                }
            }else {
                throw new BizException("目前仅支持6种常规判断类型，包括（等于、不等于、大于、大于等于、小于、小于等于）");
            }
        }else {
            throw  new BizException("条件判断目前仅支持字符串、数字");
        }
        return false;
    }
    // 并行网关，确认其他节点是否完成
    public  Boolean completeAllParallel(String target){
        JSONArray stateList = workOrderDetails.getState();
        this.cirHistoryList = workOrderCirculationHistoryService.list(new QueryWrapper<>(new WorkOrderCirculationHistory()).eq("work_order", workOrderDetails.getId()));
        if(stateList != null && stateList.size() > 0){
            continueHistoryTag:
            for (int i = 0; i < this.cirHistoryList.size(); i++) {
                boolean status = false;
                WorkOrderCirculationHistory circulationHistory = this.cirHistoryList.get(i);
                for (int j = 0; j < stateList.size(); j++) {
                    if(circulationHistory.getSource().equals(stateList.getJSONObject(j).getString("id")) &&
                            circulationHistory.getTarget().equals(target)){
                        status = true;
                        List<Object> objects = stateList.subList(i, stateList.size() - 1);
                        stateList.clear();
                        stateList.addAll(objects);
                        continue continueHistoryTag;
                    }
                }
                if (!status ){
                    break;
                }
            }
            if(stateList.size()==1 && stateList.getJSONObject(0).getString("id").equals(stateValue.getString("id"))){
                return true;
            }
            return false;
        }
        return false;
    }
    public void commonProcessing(){
        if (this.flowProperties == 0){
            circulation();
            return;
        }
        //会签
        JSONArray assignValue = this.stateValue.getJSONArray("assignValue");
        if (assignValue != null && assignValue.size() > 0) {
            Boolean isCounterSign = this.stateValue.getBoolean("isCounterSign");
            if (isCounterSign) {
                this.endHistory = false;
                circulation();
            }else {
                circulation();
            }
        }else{
            circulation();
        }
    }

    public void HandleWorkOrder(HandleParamVO handleParamVO) {
        this.flowProperties = handleParamVO.getFlow_properties();
        this.endHistory = true;
        this.workOrderId = handleParamVO.getWork_order_id();
        Long userId = ContextUtil.getUserId();
        //获取工单信息
        this.workOrderDetails = workOrderInfoService.getById(workOrderId);
        //查询创建人信息
        User applyUserInfo = userService.getById(workOrderDetails.getCreatedBy());
        //获取流程信息
        ProcessInfo processInfo = processInfoService.getById(workOrderDetails.getProcess());
        JSONObject structure = processInfo.getStructure();
        ProcessState processState = new ProcessState(structure.getJSONArray("nodes"));
        //获取当前节点
        this.stateValue = processState.getNode(handleParamVO.getSource_state());
        //目标状态
        this.targetStateValue = processState.getNode(handleParamVO.getTarget_state());
        //获取工单数据
        List<WorkOrderTplData> workOrderTplDataList = workOrderTplDataService.list(new QueryWrapper<>(new WorkOrderTplData()).eq("work_order", workOrderId));
        this.workOrderData = workOrderTplDataList.stream().map(WorkOrderTplData::getFormData).collect(Collectors.toList());
        this.cirHistoryList  = workOrderCirculationHistoryService.list(new QueryWrapper<>(new WorkOrderCirculationHistory()).eq("work_order", workOrderDetails.getId()));
        JSONArray relatedPersonList = workOrderDetails.getRelatedPerson();
        boolean relatePersonStatus = false;
        for (int i = 0; i < relatedPersonList.size(); i++) {
            Long id = relatedPersonList.getLong(i);
            if(id.equals(userId)){
                relatePersonStatus = true;
                break;
            }
        }
        if(!relatePersonStatus){
            relatedPersonList.add(userId);
        }

        JSONArray addStateValue = new JSONArray();
        JSONObject stateValueWorkOrderInfo = new JSONObject();
        JSONArray relatePersonValue = new JSONArray(relatedPersonList);
        this.updateValue.put("related_person", relatePersonValue);

        stateValueWorkOrderInfo.put("id", this.targetStateValue.getString("id"));
        stateValueWorkOrderInfo.put("label", this.targetStateValue.getString("label"));
        ProcessState edgesProcess = new ProcessState(structure.getJSONArray("edges"));
        JSONArray sourceEdges = edgesProcess.getEdge(this.targetStateValue.getString("id"), "source");
        String clazz = this.targetStateValue.getString("clazz");
        switch (clazz) {
            //排他网关
            case "exclusiveGateway":
                WorkOrderTplData tplParam = new WorkOrderTplData();
                tplParam.setWorkOrder(workOrderId);
                this.workOrderTplData = this.workOrderTplDataService.list(new QueryWrapper<>(tplParam));
                breakTag:
                for (int i = 0; i < sourceEdges.size(); i++) {
                    JSONObject edge = sourceEdges.getJSONObject(i);
                    JSONArray edgeCondExpr = edge.getJSONArray("conditionExpression");
                    if(edgeCondExpr != null && !edgeCondExpr.isEmpty()){
                        for (int j = 0; j < edgeCondExpr.size(); j++) {
                            JSONObject condExpr = edgeCondExpr.getJSONObject(j);
                            //条件判断
                            this.condExprStatus = ConditionalJudgment(condExpr);
                            if(this.condExprStatus ){
                                this.targetStateValue = processState.getNode(edge.getString("target"));
                                if (this.targetStateValue == null) {
                                   throw new BizException("未发现跳转节点");
                                }
                                if(this.targetStateValue.getString("clazz").equals("userTask") ||
                                    this.targetStateValue.getString("clazz").equals("receiveTask") ){
                                    if(  this.targetStateValue.getJSONArray("assignValue")==null||
                                            this.targetStateValue.getString("assignType").equals("")){
                                       throw new BizException("处理人不能为空");
                                    }
                                }
                                JSONObject addUpdateValue = new JSONObject();
                                addUpdateValue.put("id", this.targetStateValue.getString("id"));
                                addUpdateValue.put("label", this.targetStateValue.getString("label"));
                                addUpdateValue.put("processor", this.targetStateValue.getJSONArray("assignValue"));
                                addUpdateValue.put("process_method", this.targetStateValue.getString("assignType"));
                                JSONArray addJsonArray = new JSONArray();
                                addJsonArray.add(addUpdateValue);
                                this.updateValue.put("state", addJsonArray);
                                this.commonProcessing();
                                break breakTag;
                            }
                        }
                    }
                }
                if (!this.condExprStatus) {
                  throw  new BizException("所有流转均不符合条件，请确认。");
                }
                break;

            //并行/聚合网关
            case "parallelGateway":
            // 入口判断
                JSONArray targetEdges = edgesProcess.getEdge(this.targetStateValue.getString("id"), "target");
                if(targetEdges == null){
                    throw      new BizException("查询流转信息失败");
                }
                if(sourceEdges.size() > 0){
                    this.targetStateValue = processState.getNode(sourceEdges.getJSONObject(0).getString("target"));
                    if(this.targetStateValue ==null){
                        return;
                    }
                }else{
                    throw    new BizException("并行网关流程不正确");
                }
                if (sourceEdges.size() > 1 && targetEdges.size() == 1) {
                    //入口
                    JSONArray startJsonArray = new JSONArray();
                    this.updateValue.put("state", startJsonArray);
                    for (int i = 0; i < sourceEdges.size(); i++) {
                        JSONObject edge = sourceEdges.getJSONObject(i);
                        this.targetStateValue = processState.getNode(edge.getString("target"));
                        if(this.targetStateValue.isEmpty()){
                            return;
                        }
                        JSONObject addUpdateValue = new JSONObject();
                        addUpdateValue.put("id", edge.getString("target"));
                        addUpdateValue.put("label", this.targetStateValue.getString("label"));
                        addUpdateValue.put("processor", this.targetStateValue.getJSONArray("assignValue"));
                        addUpdateValue.put("process_method", this.targetStateValue.getString("assignType"));
//                        JSONArray addJsonArray = new JSONArray();
//                        addJsonArray.add(addUpdateValue);
                        this.updateValue.getJSONArray("state").add(addUpdateValue);
                        this.circulation();
                    }
                }else if (sourceEdges.size() == 1 && targetEdges.size() > 1) {
                    boolean parallelStatusOk = this.completeAllParallel(sourceEdges.getJSONObject(0).getString("target"));
                    if (parallelStatusOk) {
                        JSONArray assignValue = this.targetStateValue.getJSONArray("assignValue");
                        if(assignValue.isEmpty()){
                            assignValue = new JSONArray();
                        }
                        String endAssignType = this.targetStateValue.getString("assignType");
                        if (endAssignType == null) {
                            endAssignType = "";
                        }
                        JSONObject addUpdateValue = new JSONObject();
                        addUpdateValue.put("id", this.targetStateValue.getString("id"));
                        addUpdateValue.put("label", this.targetStateValue.getString("label"));
                        addUpdateValue.put("processor", assignValue);
                        addUpdateValue.put("process_method", endAssignType);
//                        JSONArray addJsonArray = new JSONArray();
//                        addJsonArray.add(addUpdateValue);
                        this.updateValue.getJSONArray("state").add(addUpdateValue);
                        this.circulation();
                    }else{
                        this.endHistory = false;
                    }
                }else{
                    throw   new BizException("并行网关流程不正确");
                }
                break;
            //包容网关
            case "inclusiveGateway":
                break;
            case "start":
                JSONArray processors = new JSONArray();
                processors.add(this.workOrderDetails.getCreatedBy());
                stateValueWorkOrderInfo.put("processor", processors);
                stateValueWorkOrderInfo.put("process_method", "person");
                addStateValue.add(stateValueWorkOrderInfo);
                this.updateValue.put("state", addStateValue);
                this.circulation();
                break;
            case "userTask":

                stateValueWorkOrderInfo.put("processor", this.targetStateValue.getJSONArray("assignValue"));
                stateValueWorkOrderInfo.put("process_method", this.targetStateValue.getString("assignType"));
                addStateValue.add(stateValueWorkOrderInfo);
                this.updateValue.put("state", addStateValue);
                this.commonProcessing();
                break;
            case "receiveTask":
                stateValueWorkOrderInfo.put("processor", this.targetStateValue.getJSONArray("assignValue"));
                stateValueWorkOrderInfo.put("process_method", this.targetStateValue.getString("assignType"));
                addStateValue.add(stateValueWorkOrderInfo);
                this.updateValue.put("state", addStateValue);
                this.commonProcessing();
                break;
            case "scriptTask":
                stateValueWorkOrderInfo.put("processor",new ArrayList<>());
                stateValueWorkOrderInfo.put("process_method","");
                addStateValue.add(stateValueWorkOrderInfo);
                this.updateValue.put("state", addStateValue);
                break;
            case "end":
                stateValueWorkOrderInfo.put("processor",new ArrayList<>());
                stateValueWorkOrderInfo.put("process_method","");
                addStateValue.add(stateValueWorkOrderInfo);
                this.updateValue.put("state", addStateValue);
                this.commonProcessing();
                break;
            default:
                System.err.println("流程执行了");
                break;
        }
/**
 *	paramsValue        struct {
 * 			Id       int           `json:"id"`
 * 			Title    string        `json:"title"`
 * 			Priority int           `json:"priority"`
 * 			FormData []interface{} `json:"form_data"`
 *                }
 */


        ParamsValue paramsValue = new ParamsValue();
        for (int i = 0; i < handleParamVO.getTpls().size(); i++) {
            JSONObject tpl = handleParamVO.getTpls().getJSONObject(i);
            JSONObject tplValue = tpl.getJSONObject("tplValue");
            paramsValue.setFormData(tplValue);
            //是否可写，只有可写的模板可以更新数据
            boolean updateStatus = false;
            if ("start".equals(this.stateValue.getString("clazz"))) {
                updateStatus = true;
            }else if( this.stateValue.getJSONArray("writeTpls")!=null && this.stateValue.getJSONArray("writeTpls").size() > 0){
                JSONArray writeTplList = stateValue.getJSONArray("writeTpls");
                tplListTag:
                for (int j = 0; j < writeTplList.size(); j++) {
                    Long writeTplId = writeTplList.getLong(j);
                    if(writeTplId.equals(tpl.getLong("tplId"))){
                        JSONArray hideTplList = this.stateValue.getJSONArray("hideTpls");
                        if (hideTplList != null && hideTplList.size() > 0) {
                            for (int h = 0; h < hideTplList.size(); h++) {
                                Long hideTplId = hideTplList.getLong(h);
                                if (hideTplId.equals(tpl.getString("tplId"))) {
                                    updateStatus = false;
                                    break tplListTag;
                                }else{
                                    updateStatus = true;
                                }
                            }
                        }else{
                            updateStatus = true;
                        }
                    }
                }
            }else{
                //不可写
                updateStatus = false;
            }
            if(updateStatus){
                WorkOrderTplData workOrderTplData = new WorkOrderTplData();
                workOrderTplData.setId(tpl.getLong("tplDataId"));
                workOrderTplData.setFormData(tplValue);
                boolean b = workOrderTplDataService.updateById(workOrderTplData);
                if(!b){
                    throw   new BizException("工单数据修改失败");
                }
            }
        }
        List<WorkOrderCirculationHistory> cirHistoryValue = workOrderCirculationHistoryService.list(new QueryWrapper<>(new WorkOrderCirculationHistory())
                .eq("work_order", workOrderId)
                .orderByDesc("create_time"));
        Long costDurationValue = 0L;
        for (int i = 0; i < cirHistoryValue.size(); i++) {
            if (cirHistoryValue.get(i).getSource().equals(this.stateValue.getString("id"))) {
                LocalDateTime createTime = cirHistoryValue.get(i).getCreateTime();
                costDurationValue = this.until(createTime);

            }
        }
        WorkOrderCirculationHistory build = WorkOrderCirculationHistory
                .builder()
                .createdBy(ContextUtil.getUserId())
                .createTime(LocalDateTime.now())
                .title(this.workOrderDetails.getTitle())
                .workOrder(workOrderId)
                .state(this.stateValue.getString("label"))
                .source(this.stateValue.getString("id"))
                .target(this.targetStateValue.getString("id"))
                .circulation(handleParamVO.getCirculation())
                .processor(ContextUtil.getName())
                .processorId(ContextUtil.getUserId())
                .status(flowProperties).delFlag(false)
                .costDuration(String.valueOf(costDurationValue))
                .remarks(handleParamVO.getRemarks()).build();

        boolean historySave = workOrderCirculationHistoryService.save(build);
        if(!historySave){
            throw  new BizException("工单历史记录新增失败");
        }
        // 获取流程通知类型列表
        JSONArray noticeList = processInfo.getNotice();
        //发送邮件（未开发）
        /*	// 获取流程通知类型列表
	err = json.Unmarshal(processInfo.Notice, &noticeList)
	if err != nil {
		return
	}

	// 获取需要抄送的邮件
	emailCCList := make([]string, 0)
	if h.stateValue["cc"] != nil && len(h.stateValue["cc"].([]interface{})) > 0 {
		err = orm.Eloquent.Model(&system.SysUser{}).
			Where("user_id in (?)", h.stateValue["cc"]).
			Pluck("email", &emailCCList).Error
		if err != nil {
			err = errors.New("查询邮件抄送人失败")
			return
		}
	}

	bodyData := notify.BodyData{
		SendTo: map[string]interface{}{
			"userList": sendToUserList,
		},
		EmailCcTo:   emailCCList,
		Subject:     sendSubject,
		Description: sendDescription,
		Classify:    noticeList,
		ProcessId:   h.workOrderDetails.Process,
		Id:          h.workOrderDetails.Id,
		Title:       h.workOrderDetails.Title,
		Creator:     applyUserInfo.NickName,
		Priority:    h.workOrderDetails.Priority,
		CreatedAt:   h.workOrderDetails.CreatedAt.Format("2006-01-02 15:04:05"),
	}
        * */
        //判断目标是否是结束节点
        String sendSubject = "您有一条待办工单，请及时处理";
        String sendDescription = "您有一条待办工单请及时处理，工单描述如下";
        if(this.targetStateValue.getString("clazz").equals("end") && this.endHistory){
            sendSubject = "您的工单已处理完成";
            sendDescription = "您的工单已处理完成，工单描述如下";
            WorkOrderCirculationHistory tx = WorkOrderCirculationHistory
                    .builder()
                    .createdBy(ContextUtil.getUserId())
                    .createTime(LocalDateTime.now())
                    .title(this.workOrderDetails.getTitle())
                    .workOrder(workOrderId)
                    .state(this.targetStateValue.getString("label"))
                    .source(this.targetStateValue.getString("id"))
                    .circulation("结束")
                    .delFlag(false)
                    .processor(ContextUtil.getName())
                    .processorId(ContextUtil.getUserId())
                    .status(2)
                    .remarks("工单结束").build();
            boolean historySaveTx = workOrderCirculationHistoryService.save(tx);
            WorkOrderInfo workOrderInfo = new WorkOrderInfo();
            workOrderInfo.setId(this.workOrderId);
            workOrderInfo.setIsEnd(1);
            workOrderInfoService.updateById(workOrderInfo);
            if(!historySaveTx){
                throw new BizException("结束工单历史记录新增失败");
            }
            this.circulation();
            // 发送通知
            if (noticeList.size() > 0) {
//                JSONArray stateList = this.updateValue.getJSONArray("state");
//                StateController stateController = new StateController(userService,orgService);
//                List<User> users = stateController.GetPrincipalUserInfo(stateList, this.workOrderDetails.getCreatedBy());
                //发送邮件 或者通知（未开发）
            }
//            if (handleParamVO.getIs_exec_task()) {
                //执行公共任务及节点任务 （未开发）
//            }
        }



    }
    /**
     * 计算结束时间与当前时间间隔的天数
     *
     * @param startDate 结束日期
     * @return 计算结束时间与当前时间间隔的分钟
     */
    public long until(LocalDateTime startDate) {
        return startDate.until(LocalDateTime.now(), ChronoUnit.MINUTES);
    }
@Data
 class ParamsValue {
    private Long id;
    private String title;
    private Long priority;
    private JSONObject formData;

}


@Data
 class Expr{
    public  final List<String> fh = new ArrayList<>();
    Expr(){
        this.fh.add(eq);
        this.fh.add(notEq);
        this.fh.add(gt);
        this.fh.add(gtEq);
        this.fh.add(lt);
        this.fh.add(ltEq);
    }
    private  String eq = "==";
    private  String notEq = "==";
    private  String gt = ">";
    private  String gtEq = ">=";
    private  String lt = "<";
    private  String ltEq = "<=";
}

}








































